package com.winchain.chainbill.bill.biz.repurchase.rx;

import com.shell.bee.acct.account.po.AcctBas;
import com.shell.bee.acct.account.po.AcctBkp;
import com.shell.bee.acct.account.util.VirtualAcctUtil;
import com.shell.bee.acct.transaction.po.AcctTxRec;
import com.shell.bee.acct.transaction.vo.AcctInfo;
import com.shell.bee.base.exception.UnCheckException;
import com.shell.bee.base.exception.UnCheckMsgException;
import com.shell.bee.base.utils.SpringContextUtil;
import com.shell.bee.base.utils.SystemUtil;
import com.shell.constant.rel.AssetCode;
import com.shell.framework.rx.OnErrorNotImplementedSubscriber;
import com.shell.framework.utils.SysDateUtil;
import com.winchain.chainbill.ChainBillUtil;
import com.winchain.chainbill.bill.base.po.CbRec;
import com.winchain.chainbill.bill.base.po.CbRpur;
import com.winchain.chainbill.bill.biz.Bill;
import com.winchain.chainbill.bill.biz.BillEvent;
import com.winchain.chainbill.trade.service.BillAcctBlcService;
import com.winchain.chainbill.trade.service.BillAcctService;
import com.winchain.chainbill.trade.service.TradeService;
import java.math.BigDecimal;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class BillRpurDebitSubscriber extends OnErrorNotImplementedSubscriber<BillEvent<CbRpur>> {
	@Autowired
	private BillAcctService billAcctService;
	@Autowired
	private BillAcctBlcService billAcctBlcService;
	@Autowired
	private TradeService tradeService;

	public void onApplicationEvent(BillEvent<CbRpur> t) {
		if (ChainBillUtil.onlinePay()) {
			CbRec record = t.getBill().getRec();
			CbRpur cbRpur = (CbRpur) t.getBill().getSource();
			if (cbRpur != null) {
				AcctTxRec tran = getAcctTxRec(record, cbRpur);
				Map<String, String> result = this.tradeService.fire(tran);
				t.setValue("pmtResult", result.get("ret_code"));
				if (!"S".equals(result.get("ret_code"))) {
					throw new UnCheckException("��������");
				}
			}
		}
	}

	private AcctTxRec getAcctTxRec(CbRec record, CbRpur cbRpur) {
		String grpId = record.getGrpId();
		AcctTxRec txRec = new AcctTxRec();
		txRec.setTxId(SystemUtil.getUUID());
		txRec.setTxSn(SystemUtil.getUUID());
		txRec.setBizId(record.getBillId());
		txRec.setTxAmt(cbRpur.getRpurAmt().subtract(cbRpur.getRpurInt()));
		txRec.setTxType("cb_hld_pmt");
		txRec.setCurrCode(AssetCode.CNY.name());
		txRec.setTxChnCode("B");
		txRec.setOptType("qt_trd");
		txRec.setTxAbs("����������");

		AcctBas txAcct = this.billAcctService.getAcctBas(cbRpur.getBuyerId(), null, "00");
		if (txAcct != null) {
			txRec.setTxAcctNo(txAcct.getAcctNo());
			txRec.setTxAcctNm(txAcct.getAcctNm());
			txRec.setTxBankNm(txAcct.getFiNm());
			if ((ChainBillUtil.onlinePay()) && (VirtualAcctUtil.onVirtual())
					&& (!checkBalance(txAcct, grpId, txRec.getTxAmt()))) {
				throw new UnCheckMsgException("��������������������������������");
			}
			AcctBkp txAcctBkp = this.billAcctBlcService.getAcctBkp(txRec.getTxAcctNo(), txRec.getCurrCode(), grpId,
					null);
			txRec.setTxBkpId(txAcctBkp.getBkpId());
		}
		AcctBas cpAcct = this.billAcctService.getAcctBas(record.getFinId(), null, "00");
		if (cpAcct != null) {
			txRec.setCpAcctNo(cpAcct.getAcctNo());
			txRec.setCpAcctNm(cpAcct.getAcctNm());
			txRec.setCpBankNm(cpAcct.getFiNm());
			AcctBkp cpAcctBkp = this.billAcctBlcService.getAcctBkp(txRec.getCpAcctNo(), txRec.getCurrCode(), grpId,
					null);
			txRec.setCpBkpId(cpAcctBkp.getBkpId());
		}
		txRec.setTxId(SystemUtil.getUUID());
		txRec.setTxDt(SysDateUtil.getSystemDate());
		txRec.setTxTs(SysDateUtil.getSystemDateTime());
		txRec.setTxSts("I");
		String sourceCode = SpringContextUtil.getProperty("system.code");
		txRec.setSrcCode(sourceCode);
		txRec.setDataScLvl("B");
		txRec.setTxCashFlag("N");
		txRec.setTxReqFiCls("1");
		txRec.setTxOperator("System");
		return txRec;
	}

	private boolean checkBalance(AcctBas txAcct, String grpId, BigDecimal amount) {
		boolean flag = true;
		String acctNo = txAcct.getAcctNo();
		try {
			this.billAcctBlcService.getBankAcctBlc(acctNo);
		} catch (Exception e) {
			this.logger.error("��������������������");
			e.printStackTrace();
		}
		AcctInfo acctInfo = new AcctInfo();
		acctInfo.setAcctNo(acctNo);
		acctInfo.setAcctType("1");
		acctInfo.setCurrCode(AssetCode.CNY.name());
		acctInfo.setBkpPrdCode(grpId);
		AcctInfo bas = this.billAcctService.getAcctCardInfo(acctInfo);
		if (bas.getAvailableAmt().compareTo(amount) < 0) {
			flag = false;
		}
		return flag;
	}
}
